var log = function (text) { console.log("[MySiteTool]: %c" + text, 'background: #bada55; color: #000'); }
var out = function (text) { jQuery("#outputWindow").append(text + "\n"); }
var puke = function (text) { console.log("[MySiteTool]: %c" + text, 'background: #ff1111; color: #000'); }

clear();

function mysiteMasterPageUploader(isBranding) {
    var _this = this;
    _this.arrayBuffer;
    _this.fileData;
    _this.fileInput;
    _this.fileName;
    _this.isBranding = isBranding;
    _this.users;
    _this.props = {};
    _this.ctxs = [];
    _this.usersWithSite = [];
    _this.usersNoSite = [];

    var ctx = SP.ClientContext.get_current();

    function downloadMasterPage() {
        _this.fileName = jQuery("#masterPageTitle").val();
        var url = _spPageContextInfo.siteAbsoluteUrl + "/_catalogs/masterpage/" + _this.fileName;
        log("downloading file from " + url);
        var promise = jQuery.ajax({
            url: url,
            headers: {
                "accept": "application/json;odata=verbose"
            }
        });
        promise.done(function (data) {
            _this.fileData = data;
            log("File downloaded");
        });
        return promise;
    }

    function getFileBuffer() {
        log("Buffering file");
        _this.fileInput = jQuery('#getFile');
        var parts = _this.fileInput[0].value.split('\\');
        _this.fileName = parts[parts.length - 1];
        log("Loading file: " + _this.fileName);

        var deferred = jQuery.Deferred();
        deferred.done(function (arrayBuffer) {
            _this.arrayBuffer = arrayBuffer;
        });
        var reader = new FileReader();
        reader.onloadend = function (e) {
            deferred.resolve(e.target.result);
        }
        reader.onerror = function (e) {
            deferred.reject(e.target.error);
        }
        reader.readAsArrayBuffer(_this.fileInput[0].files[0]);
        return deferred.promise();
    }

    function getUsers() {
        log("Getting users");

        var deferred = jQuery.Deferred();
        deferred.done(function (users) {
            _this.users = users;
        });
        var web = ctx.get_web();
        var users = web.get_siteUsers();

        ctx.load(users);
        ctx.executeQueryAsync(
            function () {
                deferred.resolve(users);
            }, function (sender, args) {
                deferred.reject(sender, args, errorMsg);
            });
        return deferred.promise();
    }

    function getUserProperties() {
        log("Getting all users properties");
        var upm = new SP.UserProfiles.PeopleManager(ctx);
        var en = _this.users.getEnumerator();
        var prefix = 'i:0#.f|membership|';
        var props = [];
        
        while (en.moveNext()) {
            var user = en.get_current();
            var login = user.get_loginName();
            if (login.indexOf(prefix) == -1) continue;
            log("Current user: " + login);
            var prop = upm.getPropertiesFor(login);
            if (!(login in props)) {
                props[login] = prop;
                ctx.load(prop);
            }
        }
        _this.props = props;

        var deferred = jQuery.Deferred();
        ctx.executeQueryAsync(
            function () {
                deferred.resolve();
            }, function (sender, args) {
                deferred.reject(sender, args, errorMsg);
            });
        return deferred.promise();
    }

    function getPersonalSites() {
        log("Getting all users personal sites");
        var urlSearchKey = "/personal/";
        for (var key in _this.props) {
            var prop = _this.props[key];
            try {
                var url = prop.get_personalUrl();
                log("Personal site URL: " + url);
                if (url.indexOf(urlSearchKey) < 0) {
                    _this.usersNoSite.push(key);
                    continue;
                }
                _this.usersWithSite.push(key);
                if (_this.isBranding) {
                    _this.ctxs.push(new personalSiteContext(url, _this.fileData, _this.fileName));
                }
            }
            catch (e) {
                puke(e.message);
            }
        }
        var dfr = jQuery.Deferred();
        dfr.resolve();
        return dfr.promise();
    }
   
    function displayUsersNoSite() {
        log("users with no personal site");
        for (var i = 0; i < _this.usersNoSite.length; i++) {
            out(_this.usersNoSite[i].replace("i:0#.f|membership|", ''));
        }
    }

    function onError(error) {
        puke(error.responseText);
    }

    if (_this.isBranding) {
        downloadMasterPage()
        .then(getUsers)
        .then(getUserProperties)
        .then(getPersonalSites);
    } else {
        getUsers()
        .then(getUserProperties)
        .then(getPersonalSites)
        .then(displayUsersNoSite);
    }
}

function personalSiteContext(url, fileData, fileName) {
    //if (url != "https://laurentmec1-my.sharepoint.com/personal/manishc_laurentmec1_onmicrosoft_com/") return;
    var _this = this;
    _this.fileData = fileData;
    _this.fileName = fileName;
    _this.folderUrl = '_catalogs/masterpage/';
    _this.token;
    _this.url = url;
    _this.uploadStatus;
    _this.web;

    getDigestToken()
    .then(uploadFile)
    .then(setMasterPage);
    //.fail(addAdmin);

    function getDigestToken() {
        var promise = jQuery.ajax({
            url: _this.url + "/_api/contextinfo",
            type: "POST",
            headers: {
                "Accept": "application/json; odata=verbose"
            },
            contentType: "application/json;odata=verbose",
            success: function (data) {
                _this.token = data.d.GetContextWebInformation.FormDigestValue;
                log("Digest token: " + _this.token);
            },
            error: function (e) {
                console.log(e);
            }
        });
        return promise;
    }

    function uploadFile() {
        log("Uploading the file to " + _this.url + "/" + _this.folderUrl);
        var fileCollectionEndpoint = String.format("{0}/_api/web/getfolderbyserverrelativeurl('{1}')/files/add(overwrite=true, url='{2}')", _this.url, _this.folderUrl, _this.fileName);
        var promise = jQuery.ajax({
            url: fileCollectionEndpoint,
            type: "POST",
            data: _this.fileData,
            processData: false,
            headers: {
                "accept": "application/json;odata=verbose",
                "X-RequestDigest": _this.token
            }
        });
        promise.done(function () { log("uploaded succesfully")});
        return promise;
    }

    function setMasterPage() {
        var _ctx = new SP.ClientContext(_this.url);
        var site = _ctx.get_site();
        _this.web = site.openWeb("blog");

        var masterPageUrl = _this.url + _this.folderUrl + _this.fileName;
        masterPageUrl = "/" + masterPageUrl.split("/").slice(3).join("/");
        
        var webProps = _this.web.get_allProperties();
        log("Full Masterpage Url: " + masterPageUrl);
        log("Setting new master page");
        
        webProps.set_item('__InheritsCustomMasterUrl', false);
        _this.web.set_masterUrl(masterPageUrl);
        _this.web.set_customMasterUrl(masterPageUrl);
        _this.web.update();
        
        log("Applying changes");
        
        var _ctx = _this.web.get_context();
        _ctx.executeQueryAsync(function () { log("DONE: " + _this.url); }, function (e) { console.log(e); });
    }

    function addAdmin() {
        var deferred = jQuery.Deferred();
        var ctx = new SP.ClientContext(_this.url);
        var web = ctx.get_web();
        var user = web.get_currentUser();
        // exe?
        var rd = SP.RoleDefinitionBindingCollection.newObject(ctx);
        rd.add(ctx.get_web().get_roleDefinitions().getByType(SP.RoleType.administrator));
        web.get_roleAssignments().add(user, rd);
        log("adding admin to " + _this.url);
        ctx.load(user);
        ctx.executeQueryAsync(
            function () {
                console.log("Added Success to ", _this.url);
                deferred.resolve();
            }, function (sender, args) {
                deferred.reject(sender, args);
                console.log("Fail ", _this.url);
            });
        return deferred.promise();
    }

    return _this;
}

SP.SOD.registerSod('jquery.js', "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js");
SP.SOD.executeFunc('SP.js', 'SP.ClientContext', function () {
    SP.SOD.executeFunc('jquery.js', 'jQuery.each', function () {
        SP.SOD.executeFunc('userprofile', 'SP.UserProfiles.PeopleManager', function () {
            var form = '<fieldset>                                                                          \
                            <legend>Personal Site Provision</legend>                                        \
                            <label for="title">Get User Without Personal Site</label>                       \
                            <input type="button" value="Get users" id="getUsersButton" name="title" />      \
                            <br />                                                                          \
                        </fieldset>                                                                         \
                        <fieldset>                                                                          \
                            <legend>Master Page</legend>                                                    \
                            <label for="name">Master Page Title:</label>                                    \
                            <input type="text" name="name" id="masterPageTitle" value="mysiteadra1.master"/>\
                            <br />                                                                          \
                            <input id="addFileButton" type="button" value="Upload">                         \
                            <br />                                                                          \
                        </fieldset>                                                                         \
                        <fieldset>                                                                          \
                            <legend>Output</legend>                                                         \
                            <textarea id="outputWindow" name="Text1" cols="100" rows="25" readonly></textarea> \
                        </fieldset>';
            jQuery("#contentBox").html(form);
            jQuery("#addFileButton").click(function () { mysiteMasterPageUploader(1) });
            jQuery("#getUsersButton").click(function () { mysiteMasterPageUploader(0) });
            log("From ready");
        });
    });
});